/**
 * 数据验证工具函数
 */

import { ErrorType, type ValidationError } from '../types/errors'
import { HISTORY_CONSTANTS, SEARCH_CONSTANTS } from '../types/constants'
import { ErrorHandler } from './error-handler'

// 验证结果类型
export type ValidationResult = {
  isValid: boolean
  errors: ValidationError[]
}

// 验证器类
export class Validator {
  /**
   * 验证历史版本ID格式
   */
  static validateVersionId(versionId: string): ValidationResult {
    const errors: ValidationError[] = []

    if (!versionId) {
      errors.push({
        field: 'versionId',
        message: '版本ID不能为空',
        code: 'REQUIRED',
        value: versionId
      })
    } else if (!HISTORY_CONSTANTS.VERSION_ID_PATTERN.test(versionId)) {
      errors.push({
        field: 'versionId',
        message: '版本ID格式无效',
        code: 'INVALID_FORMAT',
        value: versionId
      })
    }

    return {
      isValid: errors.length === 0,
      errors
    }
  }

  /**
   * 验证文件路径
   */
  static validateFilePath(filePath: string): ValidationResult {
    const errors: ValidationError[] = []

    if (!filePath) {
      errors.push({
        field: 'filePath',
        message: '文件路径不能为空',
        code: 'REQUIRED',
        value: filePath
      })
    } else {
      // 检查路径遍历攻击
      if (filePath.includes('..') || filePath.includes('~')) {
        errors.push({
          field: 'filePath',
          message: '文件路径包含不安全字符',
          code: 'UNSAFE_PATH',
          value: filePath
        })
      }

      // 检查绝对路径
      if (filePath.startsWith('/') || /^[A-Za-z]:/.test(filePath)) {
        errors.push({
          field: 'filePath',
          message: '不允许使用绝对路径',
          code: 'ABSOLUTE_PATH',
          value: filePath
        })
      }
    }

    return {
      isValid: errors.length === 0,
      errors
    }
  }

  /**
   * 验证搜索查询
   */
  static validateSearchQuery(query: string): ValidationResult {
    const errors: ValidationError[] = []

    if (!query) {
      errors.push({
        field: 'query',
        message: '搜索查询不能为空',
        code: 'REQUIRED',
        value: query
      })
    } else if (query.length < SEARCH_CONSTANTS.MIN_QUERY_LENGTH) {
      errors.push({
        field: 'query',
        message: `搜索查询至少需要${SEARCH_CONSTANTS.MIN_QUERY_LENGTH}个字符`,
        code: 'MIN_LENGTH',
        value: query
      })
    }

    return {
      isValid: errors.length === 0,
      errors
    }
  }

  /**
   * 验证文件扩展名
   */
  static validateFileExtension(fileName: string, allowedExtensions: string[]): ValidationResult {
    const errors: ValidationError[] = []

    if (!fileName) {
      errors.push({
        field: 'fileName',
        message: '文件名不能为空',
        code: 'REQUIRED',
        value: fileName
      })
      return { isValid: false, errors }
    }

    const extension = fileName.toLowerCase().substring(fileName.lastIndexOf('.'))
    
    if (!allowedExtensions.includes(extension)) {
      errors.push({
        field: 'fileName',
        message: `不支持的文件类型: ${extension}`,
        code: 'UNSUPPORTED_TYPE',
        value: fileName
      })
    }

    return {
      isValid: errors.length === 0,
      errors
    }
  }

  /**
   * 验证日期范围
   */
  static validateDateRange(startDate: Date, endDate: Date): ValidationResult {
    const errors: ValidationError[] = []

    if (!startDate) {
      errors.push({
        field: 'startDate',
        message: '开始日期不能为空',
        code: 'REQUIRED',
        value: startDate
      })
    }

    if (!endDate) {
      errors.push({
        field: 'endDate',
        message: '结束日期不能为空',
        code: 'REQUIRED',
        value: endDate
      })
    }

    if (startDate && endDate && startDate > endDate) {
      errors.push({
        field: 'dateRange',
        message: '开始日期不能晚于结束日期',
        code: 'INVALID_RANGE',
        value: { startDate, endDate }
      })
    }

    return {
      isValid: errors.length === 0,
      errors
    }
  }

  /**
   * 验证数字范围
   */
  static validateNumberRange(min: number, max: number): ValidationResult {
    const errors: ValidationError[] = []

    if (typeof min !== 'number' || isNaN(min)) {
      errors.push({
        field: 'min',
        message: '最小值必须是有效数字',
        code: 'INVALID_NUMBER',
        value: min
      })
    }

    if (typeof max !== 'number' || isNaN(max)) {
      errors.push({
        field: 'max',
        message: '最大值必须是有效数字',
        code: 'INVALID_NUMBER',
        value: max
      })
    }

    if (typeof min === 'number' && typeof max === 'number' && min > max) {
      errors.push({
        field: 'range',
        message: '最小值不能大于最大值',
        code: 'INVALID_RANGE',
        value: { min, max }
      })
    }

    return {
      isValid: errors.length === 0,
      errors
    }
  }

  /**
   * 验证并抛出错误
   */
  static validateAndThrow(validationResult: ValidationResult, context?: string): void {
    if (!validationResult.isValid) {
      const errorMessage = context 
        ? `${context}: ${validationResult.errors.map(e => e.message).join(', ')}`
        : validationResult.errors.map(e => e.message).join(', ')

      throw ErrorHandler.createError(
        ErrorType.VALIDATION_ERROR,
        errorMessage,
        validationResult.errors
      )
    }
  }

  /**
   * 组合多个验证结果
   */
  static combineValidationResults(...results: ValidationResult[]): ValidationResult {
    const allErrors = results.flatMap(result => result.errors)
    
    return {
      isValid: allErrors.length === 0,
      errors: allErrors
    }
  }
}